'''
任务执行相关的API路由
'''
from flask import Blueprint, request, jsonify, g, current_app
from psycopg2.extras import RealDictCursor
from utils.helpers import check_task_dependencies, update_task_progress, record_file_change
from services.ai_service import ai_execute_task, ai_test_task
from utils.notifications import create_notification

# 创建蓝图
execution_bp = Blueprint('execution', __name__, url_prefix='/api')

# 8. 执行任务
@execution_bp.route('/tasks/<int:subtask_id>/execute', methods=['POST'])
def execute_task(subtask_id):
    conn = g.db
    cursor = conn.cursor(cursor_factory=RealDictCursor)
    
    # 获取子任务信息
    cursor.execute('''
    SELECT 
        st.*, 
        mt.title as main_task_title, mt.description as main_task_description
    FROM sub_tasks st
    JOIN task_breakdown_versions tbv ON st.breakdown_version_id = tbv.id
    JOIN main_tasks mt ON tbv.main_task_id = mt.id
    WHERE st.id = %s
    ''', (subtask_id,))
    
    task = cursor.fetchone()
    
    if not task:
        return jsonify({
            'status': 'error',
            'message': '任务不存在'
        }), 404
    
    # 检查任务是否可执行
    if task['status'] != 'pending':
        return jsonify({
            'status': 'error',
            'message': '任务状态不是待执行'
        }), 400
    
    # 检查任务依赖是否满足
    if not check_task_dependencies(subtask_id):
        return jsonify({
            'status': 'error',
            'message': '任务存在未完成的依赖，无法执行'
        }), 400
    
    executor = request.json.get('executor', 'ai') if request.json else 'ai'
    
    # 记录开始执行的进度
    update_task_progress(subtask_id, task['progress'], 'in_progress', '开始执行任务', executor)
    
    # 创建执行记录
    cursor.execute('''
    INSERT INTO task_executions
    (sub_task_id, executor, status)
    VALUES (%s, %s, 'in_progress')
    RETURNING *
    ''', (subtask_id, executor))
    
    execution = cursor.fetchone()
    execution_id = execution['id']
    
    # 如果是AI执行
    if executor == 'ai':
        # AI执行任务
        ai_response = ai_execute_task(task)
        
        # 更新执行记录
        cursor.execute('''
        UPDATE task_executions
        SET 
            completed_at = NOW(), 
            status = 'completed', 
            ai_response = %s,
            execution_time_seconds = %s,
            execution_metrics = %s
        WHERE id = %s
        RETURNING *
        ''', (
            ai_response['result'], 
            ai_response['duration'], 
            ai_response['metrics'], 
            execution_id
        ))
        
        execution = cursor.fetchone()
        
        # 更新任务状态和进度
        cursor.execute('''
        UPDATE sub_tasks
        SET 
            status = 'completed', 
            updated_at = NOW(),
            progress = 100,
            actual_hours = %s
        WHERE id = %s
        ''', (ai_response['duration'] / 3600.0, subtask_id))
        
        # 记录状态更新
        update_task_progress(
            subtask_id, 
            100, 
            'completed', 
            '任务由AI执行完成', 
            'ai', 
            int(ai_response['duration'] / 60)
        )
        
        # 触发自动测试
        test_result = ai_test_task(task, ai_response['result'])
        
        # 保存测试结果
        cursor.execute('''
        INSERT INTO task_tests
        (execution_id, test_type, test_result, test_details)
        VALUES (%s, 'ai', %s, %s)
        ''', (execution_id, test_result['test_result'], test_result['test_details']))
        
        # 更新测试状态
        if test_result['test_result'] == 'pass':
            # 检查依赖此任务的其他任务是否可以从阻塞状态解除
            cursor.execute('''
            SELECT dependent_task_id 
            FROM task_dependencies 
            WHERE dependency_task_id = %s
            ''', (subtask_id,))
            
            dependent_tasks = cursor.fetchall()
            
            for dep_task in dependent_tasks:
                cursor.execute('SELECT * FROM sub_tasks WHERE id = %s AND status = %s', (dep_task['dependent_task_id'], 'blocked'))
                blocked_task = cursor.fetchone()
                
                if blocked_task and check_task_dependencies(blocked_task['id']):
                    update_task_progress(
                        blocked_task['id'], 
                        blocked_task['progress'], 
                        'pending', 
                        f'依赖任务 #{subtask_id} 已完成，任务可以执行'
                    )
            
            # 创建通知
            create_notification(
                'task_completed',
                f'任务 #{subtask_id} 执行成功',
                f'任务 "{task["title"]}" 已被AI成功执行并通过测试。',
                'admin',
                related_task_id=subtask_id,
                related_execution_id=execution_id
            )
        else:
            # 如果测试失败，更新任务状态为待执行
            cursor.execute('''
            UPDATE sub_tasks
            SET status = 'pending', updated_at = NOW(), progress = 90
            WHERE id = %s
            ''', (subtask_id,))
            
            update_task_progress(
                subtask_id, 
                90, 
                'pending', 
                '任务执行后测试未通过，需要重新执行', 
                'system'
            )
            
            # 创建通知
            create_notification(
                'task_failed',
                f'任务 #{subtask_id} 测试未通过',
                f'任务 "{task["title"]}" 执行后测试未通过，请检查。',
                'admin',
                related_task_id=subtask_id,
                related_execution_id=execution_id,
                priority='high'
            )
        
        conn.commit()
        
        return jsonify({
            'status': 'success',
            'message': '任务执行成功',
            'data': {
                'execution': execution,
                'test_result': test_result
            }
        })
    else:
        # 如果是人工执行，更新状态为待提交结果
        cursor.execute('''
        UPDATE task_executions
        SET status = 'pending_result'
        WHERE id = %s
        RETURNING *
        ''', (execution_id,))
        
        execution = cursor.fetchone()
        conn.commit()
        
        # 创建通知
        create_notification(
            'task_assigned',
            f'任务 #{subtask_id} 已分配',
            f'任务 "{task["title"]}" 已分配给 {executor} 执行，等待提交结果。',
            executor,
            related_task_id=subtask_id,
            related_execution_id=execution_id
        )
        
        return jsonify({
            'status': 'success',
            'message': '任务已分配，等待提交执行结果',
            'data': {
                'execution': execution
            }
        })

# 9. 提交任务执行结果
@execution_bp.route('/executions/<int:execution_id>/result', methods=['POST'])
def submit_execution_result(execution_id):
    data = request.get_json()
    
    if not data or 'result' not in data:
        return jsonify({
            'status': 'error',
            'message': '执行结果不能为空'
        }), 400
    
    conn = g.db
    cursor = conn.cursor(cursor_factory=RealDictCursor)
    
    # 获取执行记录
    cursor.execute('SELECT * FROM task_executions WHERE id = %s', (execution_id,))
    execution = cursor.fetchone()
    
    if not execution:
        return jsonify({
            'status': 'error',
            'message': '执行记录不存在'
        }), 404
    
    # 更新执行记录
    cursor.execute('''
    UPDATE task_executions
    SET completed_at = NOW(), status = 'completed', execution_log = %s
    WHERE id = %s
    RETURNING *
    ''', (data['result'], execution_id))
    
    execution = cursor.fetchone()
    
    # 更新任务状态
    cursor.execute('''
    UPDATE sub_tasks
    SET status = 'completed', updated_at = NOW()
    WHERE id = %s
    ''', (execution['sub_task_id'],))
    
    # 记录文件变更（如果有）
    if 'file_changes' in data and isinstance(data['file_changes'], list):
        for change in data['file_changes']:
            if all(k in change for k in ('file_path', 'change_type')):
                record_file_change(
                    execution_id,
                    change['file_path'],
                    change['change_type'],
                    change.get('content_before'),
                    change.get('content_after')
                )
    
    conn.commit()
    
    return jsonify({
        'status': 'success',
        'message': '执行结果提交成功',
        'data': {
            'execution': execution
        }
    })

# 10. 审核任务执行结果
@execution_bp.route('/executions/<int:execution_id>/review', methods=['POST'])
def review_execution(execution_id):
    data = request.get_json()
    
    if not data or 'status' not in data:
        return jsonify({
            'status': 'error',
            'message': '审核状态不能为空'
        }), 400
    
    conn = g.db
    cursor = conn.cursor(cursor_factory=RealDictCursor)
    
    # 获取执行记录
    cursor.execute('SELECT * FROM task_executions WHERE id = %s', (execution_id,))
    execution = cursor.fetchone()
    
    if not execution:
        return jsonify({
            'status': 'error',
            'message': '执行记录不存在'
        }), 404
    
    # 更新审核状态
    cursor.execute('''
    UPDATE task_executions
    SET review_status = %s, review_comments = %s
    WHERE id = %s
    RETURNING *
    ''', (data['status'], data.get('comments', ''), execution_id))
    
    execution = cursor.fetchone()
    
    # 如果审核不通过，更新任务状态为待执行
    if data['status'] == 'rejected':
        cursor.execute('''
        UPDATE sub_tasks
        SET status = 'pending', updated_at = NOW()
        WHERE id = %s
        ''', (execution['sub_task_id'],))
    
    # 添加审核记录
    cursor.execute('''
    INSERT INTO reviews
    (execution_id, reviewer, status, comments)
    VALUES (%s, %s, %s, %s)
    ''', (execution_id, data.get('reviewer', 'admin'), data['status'], data.get('comments', '')))
    
    conn.commit()
    
    return jsonify({
        'status': 'success',
        'message': '审核提交成功',
        'data': {
            'execution': execution
        }
    })

# 11. 回退任务执行
@execution_bp.route('/executions/<int:execution_id>/rollback', methods=['POST'])
def rollback_execution(execution_id):
    data = request.get_json()
    reason = data.get('reason', '') if data else ''
    
    conn = g.db
    cursor = conn.cursor(cursor_factory=RealDictCursor)
    
    # 获取执行记录
    cursor.execute('SELECT * FROM task_executions WHERE id = %s', (execution_id,))
    execution = cursor.fetchone()
    
    if not execution:
        return jsonify({
            'status': 'error',
            'message': '执行记录不存在'
        }), 404
    
    # 记录回退操作
    cursor.execute('''
    INSERT INTO rollback_operations
    (execution_id, operation_type, from_status, to_status, operated_by, reason)
    VALUES (%s, 'rollback_execution', %s, 'cancelled', 'admin', %s)
    ''', (execution_id, execution['status'], reason))
    
    # 获取文件变更记录
    cursor.execute('SELECT * FROM file_changes WHERE execution_id = %s', (execution_id,))
    file_changes = cursor.fetchall()
    
    # 更新执行记录为已取消
    cursor.execute('''
    UPDATE task_executions
    SET status = 'cancelled'
    WHERE id = %s
    RETURNING *
    ''', (execution_id,))
    
    execution = cursor.fetchone()
    
    # 更新任务状态为待执行
    cursor.execute('''
    UPDATE sub_tasks
    SET status = 'pending', updated_at = NOW()
    WHERE id = %s
    ''', (execution['sub_task_id'],))
    
    conn.commit()
    
    return jsonify({
        'status': 'success',
        'message': '执行已回退',
        'data': {
            'execution': execution,
            'file_changes': file_changes
        }
    }) 